//---------------------------------------------------------------------------------------------------------------------------------------------------
// <copyright file="Controller.cs" company="DarkWynter Studios">
//     Copyright (C)2007 DarkWynter Studios.  All rights reserved.
// </copyright>
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------

namespace DarkWynter.Engine.Controllers
{
    #region Using Statements
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Input;
    using System.Diagnostics;
    #endregion

    #region Controller and Key Types
    /// <summary>
    /// Supported Controller Types
    /// </summary>
    public enum ControllerType : byte
    {
        /// <summary>
        /// PC only
        /// </summary>
        PC_ONLY,
        /// <summary>
        /// Xbox 360 only
        /// </summary>
        XBOX_ONLY,
        /// <summary>
        /// PC and Xbox
        /// </summary>
        PC_AND_XBOX,
        /// <summary>
        /// None
        /// </summary>
        NONE
    }

    /// <summary>
    /// Different mouse control types
    /// </summary>
    public enum ControlType : byte
    {
        /// <summary>
        /// Motion Type
        /// </summary>
        Motion,
        /// <summary>
        /// Right Button Type
        /// </summary>
        RightButton,
        /// <summary>
        /// Left Button Type
        /// </summary>
        LeftButton,
        /// <summary>
        /// Middle Button Type
        /// </summary>
        MiddleButton,
        /// <summary>
        /// Scroll Wheel Type
        /// </summary>
        ScrollWheel
    };

    /// <summary>
    /// Different Xbox Analog control types
    /// </summary>
    public enum XboxAnalogControlType
    {
        /// <summary>
        /// Right Stick
        /// </summary>
        RIGHT_STICK,
        /// <summary>
        /// Left Stick
        /// </summary>
        LEFT_STICK,
        /// <summary>
        /// Right Trigger
        /// </summary>
        RIGHT_TRIGGER,
        /// <summary>
        /// Left Trigger
        /// </summary>
        LEFT_TRIGGER
    };

#endregion

    /// <summary>
    /// Event Publisher
    /// Game level classes observer and subscribe to these events
    /// </summary>
    public class Controller
    {
        private PlayerIndex _playerIndex = 0;
        private int _playerNumber = 0;

        /// <summary>
        /// PlayerIndex this controller checks for
        /// </summary>
        public PlayerIndex playerIndex { get { return _playerIndex; } set { _playerIndex = value; } }
        /// <summary>
        /// Integer player index associated with this controller
        /// </summary>
        public int playerNumber { get { return _playerNumber; } set { _playerNumber = value; } }

        /// <summary>
        /// Keyboard State
        /// </summary>
        public static KeyboardState keyboardState;
        /// <summary>
        /// Game Pad State
        /// </summary>
        public static GamePadState gamePadState;
        /// <summary>
        /// Mouse State
        /// </summary>
        public static MouseState mouseState;

        /// <summary>
        /// Controller Type
        /// </summary>
        public ControllerType playerControllerType = ControllerType.NONE;

        List<KeyboardControl> keyboardControls = new List<KeyboardControl>();
        List<XboxAnalogControl> xboxAnalogControls = new List<XboxAnalogControl>();
        List<XboxDigitalControl> xboxDigitalControls = new List<XboxDigitalControl>();
        List<MouseControl> mouseControls = new List<MouseControl>();
        
        /// <summary>
        /// Constructor for PC and mouse only
        /// </summary>
        /// <param name="player">Player index in ObjectLibrary</param>
        public Controller(int player) 
        {
            playerNumber = player;
            playerIndex = (PlayerIndex) player;

            mouseState = new MouseState();
            keyboardState = new KeyboardState();

            playerControllerType = ControllerType.PC_ONLY;
        }
        /// <summary>
        /// Constructor for Xbox
        /// </summary>
        /// <param name="pIndex">Controller index to associate with this controller</param>
        public Controller(PlayerIndex pIndex)
        {
            playerNumber = ((int)pIndex) - 1;
            playerIndex = pIndex;

            gamePadState = new GamePadState();

            playerControllerType = ControllerType.XBOX_ONLY;
        }
        /// <summary>
        /// Constructor for Xbox and keyboard controls
        /// </summary>
        /// <param name="player">Player index in ObjectLibrary</param>
        /// <param name="pIndex">Controller index</param>
        public Controller(int player, PlayerIndex pIndex)
        {
            playerNumber = player;
            playerIndex = pIndex;

            keyboardState = new KeyboardState();
            gamePadState = new GamePadState();
            mouseState = new MouseState();

            playerControllerType = ControllerType.PC_AND_XBOX;
        }

        /// <summary>
        /// Add a Keyboard control
        /// </summary>
        /// <param name="control">Keyboard control</param>
        public void Add(KeyboardControl control)
        {
            keyboardControls.Add(control);
        }
        /// <summary>
        /// Add a Xbox Analog control
        /// </summary>
        /// <param name="control">Xbox Analog control</param>
        public void Add(XboxAnalogControl control)
        {
            xboxAnalogControls.Add(control);
        }
        /// <summary>
        /// Add a Xbox Digital control
        /// </summary>
        /// <param name="control">Xbox Digital control</param>
        public void Add(XboxDigitalControl control)
        {
            xboxDigitalControls.Add(control);
        }
        /// <summary>
        /// Add a Mouse control
        /// </summary>
        /// <param name="control">Mouse control</param>
        public void Add(MouseControl control)
        {
            mouseControls.Add(control);
        }
        
        /// <summary>
        /// Update Method
        /// </summary>
        /// <param name="objectLibrary">Object Library</param>
        /// <param name="menuSystem">Menu System</param>
        public void Update( ref List<object> argObjects)
        {
            gamePadState = GamePad.GetState(playerIndex);
            keyboardState = Keyboard.GetState();
            mouseState = Mouse.GetState();
            
            // Update Controls if not paused
            //if (Statics_Engine.SystemSettings.gameState != Enums_Engine.EngineState.GAME_PAUSE)
            //{
                // PC
                for (int i = 0; i < keyboardControls.Count; i++)
                {
                    keyboardControls[i].Update(keyboardState, ref argObjects);
                }
                for (int i = 0; i < mouseControls.Count; i++)
                {
                    mouseControls[i].Update(mouseState, ref argObjects);
                }

                // XBOX
                for (int i = 0; i < xboxAnalogControls.Count; i++)
                {
                    xboxAnalogControls[i].Update(gamePadState, ref argObjects);
                }
                for (int i = 0; i < xboxDigitalControls.Count; i++)
                {
                    xboxDigitalControls[i].Update(gamePadState, ref argObjects);
                }
            //}
            //else
            //{
            //    // ======= Check for unpause button =========
            //}
        }

    }
}
